package org.qpcr.community.device.service;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.hswebframework.web.crud.service.GenericReactiveCrudService;
import org.qpcr.community.device.entity.DeviceModuleStateEntity;
import org.qpcr.core.event.EventBus;
import org.springframework.data.redis.core.ReactiveRedisOperations;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.util.Collection;
import java.util.Map;

/**
 * 模块状态接口
 */
@Service
@Slf4j
public class DeviceModuleStateService extends GenericReactiveCrudService<DeviceModuleStateEntity, String> {

    private final ReactiveRedisOperations<String, String> redis;
    private final EventBus eventBus;

    public DeviceModuleStateService(ReactiveRedisOperations<String, String> redis, EventBus eventBus) {
        this.redis = redis;
        this.eventBus = eventBus;
    }


    public Mono<Void> saveData(DeviceModuleStateEntity deviceModuleStateEntity) {

    //        System.out.println(JSON.toJSONString(deviceModuleStateEntity));
    String topic="/device/"+deviceModuleStateEntity.getProdectId()+"/"+deviceModuleStateEntity.getDeviceId()+"/moduleSate";

        return redis.opsForValue()
                    .set("deviceState:"+deviceModuleStateEntity.getDeviceId()+":"+deviceModuleStateEntity.getId(), JSON.toJSONString(deviceModuleStateEntity))
                    .then(eventBus
                              .publish(topic, deviceModuleStateEntity)
                              .then() ) ;
    }



    public Flux<DeviceModuleStateEntity> getList(String deviceId) {


        return redis.keys("deviceState:"+deviceId+":*")
                            .flatMap(str -> redis.opsForValue().get(str).flatMap(
                                value -> {
                                    DeviceModuleStateEntity entity = JSON.parseObject(value, DeviceModuleStateEntity.class);
                                    return Mono.just(entity);
                                }).flux()
                            );
    }



    public Mono<Map<String,Integer>> getModuleState(Collection<String> deviceIds){
        // 优先级：4(异常)>2(运行)>3(完成)>1(空闲)>0(自检中)
        return Flux.fromIterable(deviceIds)
                .flatMap(deviceId ->
                    redis.keys("deviceState:" + deviceId + ":*")
                        .collectList()
                        .flatMapMany(Flux::fromIterable)
                        .flatMap(key -> redis.opsForValue().get(key))
                        .map(value -> {
                            try {
                                DeviceModuleStateEntity entity = JSON.parseObject(value, DeviceModuleStateEntity.class);
                                String stateDec = entity.getStateDec();
                                if (stateDec != null) {
                                    com.alibaba.fastjson.JSONObject obj = JSON.parseObject(stateDec);
                                    Integer status = obj.getInteger("status");
                                    return status == null ? 0 : status;
                                }
                            } catch (Exception e) {
                                log.error("解析模块状态失败: {}", value, e);
                            }
                            return 0;
                        })
                        .collectList()
                        .map(statusList -> {
                            // 优先级从高到低：4>2>3>0>1
                            int[] priority = {4, 2, 3, 0, 1};
                            int finalStatus = 3; // 默认最低优先级（空闲）
                            for (int p : priority) {
                                if (statusList.contains(p)) {
                                    finalStatus = p;
                                    break;
                                }
                            }
                            return new java.util.AbstractMap.SimpleEntry<>(deviceId, finalStatus);
                        })
                )
                .collectMap(Map.Entry::getKey, Map.Entry::getValue);
    }

    public Mono<Integer> getModuleStateMono(String deviceId) {
        // 优先级：4(异常)>2(运行)>3(完成)>1(空闲)>0(自检中)
        return redis.keys("deviceState:" + deviceId + ":*")
                .collectList()
                .flatMapMany(Flux::fromIterable)
                .flatMap(key -> redis.opsForValue().get(key))
                .map(value -> {
                    try {
                        DeviceModuleStateEntity entity = JSON.parseObject(value, DeviceModuleStateEntity.class);
                        String stateDec = entity.getStateDec();
                        if (stateDec != null) {
                            com.alibaba.fastjson.JSONObject obj = JSON.parseObject(stateDec);
                            Integer status = obj.getInteger("status");
                            return status == null ? 0 : status;
                        }
                    } catch (Exception e) {
                        log.error("解析模块状态失败: {}", value, e);
                    }
                    return 0;
                })
                .collectList()
                .map(statusList -> {
                    // 优先级从高到低：4>2>3>0>1
                    int[] priority = {4, 2, 3, 0, 1};
                    int finalStatus = 3; // 默认最低优先级（空闲）
                    for (int p : priority) {
                        if (statusList.contains(p)) {
                            finalStatus = p;
                            break;
                        }
                    }
                    return finalStatus;
                })
                .defaultIfEmpty(3); // 如果没有找到任何状态，返回默认值3（空闲）
    }

    public Integer getModuleState(String deviceId){
        // 优先级：4(异常)>2(运行)>3(完成)>1(空闲)>0(自检中)
        try {
            // 获取所有模块状态
            java.util.List<String> keys = redis.keys("deviceState:" + deviceId + ":*").collectList().block();
            if (keys == null || keys.isEmpty()) {
                return 3; // 默认空闲
            }
            java.util.List<Integer> statusList = new java.util.ArrayList<>();
            for (String key : keys) {
                String value = redis.opsForValue().get(key).block();
                if (value != null) {
                    try {
                        DeviceModuleStateEntity entity = JSON.parseObject(value, DeviceModuleStateEntity.class);
                        String stateDec = entity.getStateDec();
                        if (stateDec != null) {
                            com.alibaba.fastjson.JSONObject obj = JSON.parseObject(stateDec);
                            Integer status = obj.getInteger("status");
                            statusList.add(status == null ? 0 : status);
                        } else {
                            statusList.add(0);
                        }
                    } catch (Exception e) {
                        log.error("解析模块状态失败: {}", value, e);
                        statusList.add(0);
                    }
                } else {
                    statusList.add(0);
                }
            }
            // 优先级从高到低：4>2>3>0>1
            int[] priority = {4, 2, 3, 0, 1};
            int finalStatus = 3; // 默认最低优先级（空闲）
            for (int p : priority) {
                if (statusList.contains(p)) {
                    finalStatus = p;
                    break;
                }
            }
            return finalStatus;
        } catch (Exception e) {
            log.error("获取模块状态失败: {}", deviceId, e);
            return 3;
        }
    }


    public Mono<Void> delete(String deviceId,String id) {

        String key="deviceState:"+deviceId+":"+id;

        return redis.opsForValue().delete(key).then();
    }

}
